﻿using Furion.CMS.Application;
using Furion.CMS.Application.Dto;
using Furion.CMS.Core;
using Furion.CMS.Core.Base;
using Furion.CMS.Web.Core;
using Furion.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Furion.CMS.Web.Controllers
{
    /// <summary>
    /// 文件上传
    /// </summary>
    [ApiController]
    [Route("api")]
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    public class FileUploadController : ControllerBase
    {
        private readonly IFileUploadProvider _uploadProvider;

        public FileUploadController(Func<string, ITransient, object> resolveNamed,
            SiteSettingAppService siteSetting)
        {
            var storageMode = siteSetting.GetTenantSettings()?.ObjectStorageMode ?? StorageMode.Local;
            _uploadProvider = resolveNamed(storageMode.ToString(), default) as IFileUploadProvider;
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("file-center/upload")]
        [ProducesResponseType(typeof(SimpleResult<string>), 200)]
        [AllowAnonymous]
        [ApiDescriptionSettings(false)]
        public async Task<IActionResult> Handler([FromForm] UploadModel request)
        {
            var result = new SimpleResult<string>();
            try
            {
                var uploadPath = $"{App.HostEnvironment.ContentRootPath}\\upload";

                if (!string.IsNullOrWhiteSpace(request.Dir))
                {
                    uploadPath += $"\\{request.Dir.Replace("/", "\\")}";
                }

                if (!Directory.Exists(uploadPath)) Directory.CreateDirectory(uploadPath);

                var fi = new FileInfo(request.File.FileName);

                var fileAlias = request.Rename ? $"{DateTime.Now:yyyyMMddHHmmss}{fi.Extension}" : fi.Name;
                var filePath = Path.Combine(uploadPath, fileAlias);

                // 文件模式为打开或创建
                using var stream = new FileStream(filePath, FileMode.OpenOrCreate);
                await request.File.CopyToAsync(stream);

                result.Success = true;
                result.Data = $"/upload/{request.Dir}{fileAlias}";
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.ErrorMessage = ex.Message;
            }

            return Ok(result);
        }

        /// <summary>
        /// 获取配置参数
        /// </summary>
        /// <returns></returns>
        [HttpGet("file-center/configre")]
        [ProducesResponseType(typeof(SimpleResult<UploadConfigre>), 200)]
        public IActionResult GetConfigre()
        {
            var result = new SimpleResult<UploadConfigre>();

            try
            {
                result.Success = true;
                result.Data = _uploadProvider.GetConfigre();
            }
            catch (Exception ex)
            {
                result.Success = false;
                result.ErrorMessage = ex.Message;
            }

            return Ok(result);
        }


        #region Cloud-Callbacks
        /// <summary>
        /// 阿里云对象存储回调
        /// </summary>
        /// <param name="callback"></param>
        /// <returns></returns>
        [HttpPost("file-center/cloud-callback/aliyun")]
        [ProducesResponseType(typeof(SimpleResult<string>), 200)]
        [AllowAnonymous]
        //[Consumes("application/x-www-form-urlencoded")]
        [ApiDescriptionSettings(false)]
        public IActionResult AliyunOSSCallbackHandler([FromForm] AliyunOSSCallbackModel callback)
        {
            return Ok(new SimpleResult<string>
            {
                Success = true,
                Data = _uploadProvider.CallbackHandler(callback)
            });
        }

        /// <summary>
        /// 腾讯云对象存储回调
        /// </summary>
        /// <param name="callback"></param>
        /// <returns></returns>
        [HttpGet("file-center/cloud-callback/tencent")]
        [ProducesResponseType(typeof(SimpleResult<string>), 200)]
        [AllowAnonymous]
        [ApiDescriptionSettings(false)]
        public IActionResult TencentCOSCallbackHandler([FromQuery] TencentCOSCallbackModel callback)
        {
            return Ok(new SimpleResult<string>
            {
                Success = true,
                Data = _uploadProvider.CallbackHandler(callback)
            });
        }
        #endregion
    }
}
